package com.example.smart_video.ui.fragment


import com.wink_172.library.fragment.BaseFragment
import com.example.smart_video.model.json.VideoClassData
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.example.cleandemo3.R
import android.content.Intent
import com.wink_172.library.view.ActionBarView
import com.example.smart_video.ui.activity.SelectClassActivity
import android.widget.SeekBar.OnSeekBarChangeListener
import android.widget.SeekBar
import com.example.smart_video.adapter.HBomeListAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.rubensousa.gravitysnaphelper.GravityPagerSnapHelper
import com.github.rubensousa.gravitysnaphelper.GravitySnapHelper.SnapListener
import com.example.smart_video.model.json.VideoData
import android.text.TextUtils
import com.wink_172.library.model.BaseDataItem
import com.example.smart_video.ui.activity.UploadVideoActivity
import org.xutils.x
import android.app.Activity
import android.graphics.Matrix
import org.xutils.common.Callback.CommonCallback
import com.alibaba.fastjson.JSON
import org.xutils.common.Callback.CancelledException
import android.graphics.SurfaceTexture
import android.media.MediaPlayer
import android.os.Message
import android.util.Log
import android.view.*
import android.widget.RelativeLayout
import com.danikula.videocache.HttpProxyCacheServer
import com.example.cleandemo3.databinding.FragmentMainBinding
import com.example.smart_video.ABpplication
import com.example.smart_video.adapter.HBomeListAdapter.SCENE_PLAY_LIST
import com.example.smart_video.model.Constants
import com.example.smart_video.model.Constants.LAST_LIST_DATA
import com.example.smart_video.model.Constants.TENCENT_BUCKET_OFFICE_URL
import com.example.smart_video.model.json.CommonRootBean
import com.example.smart_video.utils.CommonUtils
import com.example.smart_video.utils.HttpUtils
import com.wink_172.library.model.Constants.ACTIVITY_REQUEST_CODE3001
import com.wink_172.library.model.Constants.EVENT_01
import com.wink_172.library.model.Constants.EVENT_02
import com.wink_172.library.model.Constants.EVENT_03
import com.wink_172.library.model.Constants.PARAM_DATA1
import com.wink_172.library.utils.DateUtil
import com.wink_172.library.utils.MMKVTool
import com.wink_172.library.utils.SpanUtil
import java.io.IOException
import java.util.*

/**
 * @author: fcg
 * @date: 2020-11-03
 * Description:
 */
class MainFragment : BaseFragment(), TextureView.SurfaceTextureListener {
   lateinit var binding: FragmentMainBinding

    /**
     * play -- pause  icon
     */
    private var mCurrentListPos = 0
    private var inverted = false //倒序
    private var classData: VideoClassData? = null

    var mute=true;//第一次进来静音
    var mMediaPlayer: MediaPlayer? = null
    var m_surfaceView: TextureView? = null

    var sv_texture_w: Float = 0f
    var sv_texture_h: Float = 0f

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
        binding.setOnClickListener(this)
        handler = MyHandler()
        initView()
        initVideo()
        init()

        handler!!.sendEmptyMessageDelayed(Constants.EventEnum.进度条更新.ordinal, 1000)
        refresh()
        return binding.getRoot()
    }


    override fun handlerCallBack(msg: Message) {
        super.handlerCallBack(msg)
        when (msg.what) {
            Constants.EventEnum.等待播放器就绪才可暂停.ordinal->{

                if(mMediaPlayer!=null&&mMediaPlayer!!.isPlaying){
                    pausePlay()
                }else{
                    handler!!.removeMessages(Constants.EventEnum.等待播放器就绪才可暂停.ordinal)
                    handler!!.sendEmptyMessageDelayed(Constants.EventEnum.等待播放器就绪才可暂停.ordinal,100)
                }


            }
            Constants.EventEnum.进度条更新.ordinal -> {
                if (mMediaPlayer != null) {
                    val all_time = mMediaPlayer!!.duration
                    val current_pos = mMediaPlayer!!.currentPosition
                    val process = (current_pos * 100) / all_time
                    binding.progress.progress = process
                    if (all_time > 0) {
                        binding.allTime.setText(DateUtil.getSecondText2(all_time.toLong() / 1000))
                    } else {
                        //do nothing
                    }

                }
                handler!!.sendEmptyMessageDelayed(Constants.EventEnum.进度条更新.ordinal, 30)
            }
        }
    }


    fun init() {
        binding.circleTimeView2.visibility = View.GONE
        val currentTime = System.currentTimeMillis()
        val futureTime2 = 1665849601000L //2022-10-16 00:00:01

        // 与3-19时间相差总秒数->天
        val timeGap2 = ((futureTime2 - currentTime) / 1000 / (24 * 60 * 60)).toInt()
        binding.circleTimeView2.startCountDown(1, 365, timeGap2, "5W")
    }


    fun initView() {
        binding.unmute.setOnClickListener {
            binding.unmute.visibility=View.GONE
            mute=false
            mMediaPlayer?.setVolume(1f, 1f)
        }
        (binding.actionBar as ActionBarView).background = null
        (binding.actionBar as ActionBarView).setLineEnable(false)

        //开心💖💖
        (binding.actionBar as ActionBarView).updateAllContent(R.mipmap.icon_setting_sla, " ", "")
        (binding.actionBar as ActionBarView).setCallback(object : ActionBarView.ICallback {
            override fun onSendEvent(event: Int, content: String?) {
                if (event == ActionBarView.LEFT_BTN) {
                    inverted = true
                    refresh()

                } else if (event == ActionBarView.RIGHT_BTN) {
                    classData = null //手动清除分类
                    inverted = false
                    refresh()
                }
            }
        })
        binding.progress.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                // 当拖动条的滑块位置发生改变时触发该方法,在这里直接使用参数progress，即当前滑块代表的进度值

                val allTime = mMediaPlayer!!.duration

                val target = progress * allTime / 100;
                if (fromUser) {//用于主动拖拽
                    mMediaPlayer!!.seekTo(target);
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {}
            override fun onStopTrackingTouch(seekBar: SeekBar) {}
        })
        val list: List<Any?> = ArrayList()
        val homeListAdapter = HBomeListAdapter(context, list, binding.listView)
        binding.listView.init(homeListAdapter, false)
        val layoutManager = LinearLayoutManager(binding.root.context)
        binding.listView.layoutManager = layoutManager
        binding.swipeRefreshView.setOnRefreshListener {
            inverted = false
            refresh()
        }

        //item切换监听
        GravityPagerSnapHelper(Gravity.BOTTOM, true, SnapListener { position -> //切换Item之后的操作
            Log.e(TAG, "onSnap: ====>>$position")
            if (mCurrentListPos == position) {
                return@SnapListener
            }
            mCurrentListPos = position
            stopPlay()
            initVideo()

            x.task().postDelayed(Runnable { startPlayVideo(mCurrentListPos) }, 50)

        }).attachToRecyclerView(binding.listView)

    }

    /**
     * 绑定列表数据
     */
    fun initList(videoDataList: List<VideoData>) {
        val list: MutableList<Any> = ArrayList()
        val homeListAdapter = binding.listView.adapter as HBomeListAdapter?
        var start_pos = 0 //这个位置是很重要的
        if (!binding.swipeRefreshView.isRefreshing) {
            start_pos = homeListAdapter!!.dataList!!.size

        } else {
            mCurrentListPos = 0
        }
        for (i in videoDataList.indices) {
            val videoData = videoDataList[i]
            if(classData==null&&videoData.classfyId=="23"){//分类不展示
                continue
            }

            val baseDataItem = BaseDataItem(i, SCENE_PLAY_LIST)
            baseDataItem.setObjectData(videoData)


            start_pos = start_pos + 1
            baseDataItem.callback_m = object : com.wink_172.library.callback.ICallback {
                override fun onSendEvent(event: Int, vararg args: Any?) {
                    when (event) {
                        EVENT_01 ->
                            UploadVideoActivity.startActivity(activity, videoData)

                        EVENT_02 ->
                            UploadVideoActivity.startActivity(activity)

                        EVENT_03 -> SelectClassActivity.startActivity(
                            activity,
                            ACTIVITY_REQUEST_CODE3001
                        )
                    }
                }
            }


            if (TextUtils.equals("1", videoData.top)) {
                list.add(0, baseDataItem) //置顶
            } else {
                list.add(baseDataItem)
            }
        }
        if (binding.swipeRefreshView.isRefreshing) {
            binding.swipeRefreshView.isRefreshing = false
            homeListAdapter!!.swapContent(list)
            homeListAdapter.notifyDataSetChanged()
            if (list.size > 0) {
                binding.listView.scrollToPosition(0) //must  修复bug  当在n页点击刷新按钮 刷新后播放的不是url指定的视频
                x.task().postDelayed({
                    startPlayVideo(0)//第一次要手动播放视频 而且还要等列表渲染完毕才可以播放    perpare()方法比获取列表时间更早
                }, 300)
            }
        } else {
            val current_page = binding.listView.currentPage
            binding.listView.currentPage = current_page + 1
            homeListAdapter!!.appendContent(list, false)
            homeListAdapter.notifyDataSetChanged()
        }
        CommonUtils.setLastPlayPos(CommonUtils.getLastPlayPos() + 1)

        SpanUtil.create().addForeColorSection(
            "❀" + homeListAdapter.dataList!!.size + "≢",
            x.app().resources.getColor(R.color.white)
        ).showIn((binding.actionBar as ActionBarView).right_text)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK) {
            return
        }
        when (requestCode) {
            ACTIVITY_REQUEST_CODE3001 -> {
                classData = data!!.getSerializableExtra(PARAM_DATA1) as VideoClassData?
                refresh()
            }
        }
    }

    /**
     * 刷新
     */
    private fun refresh() {
        stopPlay()
        initVideo()
        binding.swipeRefreshView.isRefreshing = true
        binding.listView.currentPage = 1

        eventGetVideoList()
    }

    override fun onResume() {
        super.onResume()
        resumePlay()
    }

    override fun onPause() {
        super.onPause()

        //
        handler!!.removeMessages(Constants.EventEnum.等待播放器就绪才可暂停.ordinal)
        handler!!.sendEmptyMessageDelayed(Constants.EventEnum.等待播放器就绪才可暂停.ordinal,100)

    }

    /**
     *
     */
    override fun onDestroy() {
        super.onDestroy()
        stopPlay()
    }

    fun installData(result: String) {
        val commonRootBean = JSON.parseObject(result, CommonRootBean::class.java)

        val videoDataList = JSON.parseArray(commonRootBean.data, VideoData::class.java)
        if (!inverted) {
            Collections.shuffle(videoDataList) //打乱即可

        } else {
            Collections.reverse(videoDataList) //翻转

        }
        initList(videoDataList)

    }

    /**
     * 获取视频列表
     * page 起始值为0
     * classId 分类id
     */
    private fun eventGetVideoList() {
        HttpUtils.eventGetVideoList(classData,

                object :
        com.wink_172.library.callback.ICallback {
        override fun onSendEvent(event: Int,vararg args: Any?) {//这个callback用的非常巧妙    //这里因为不能传递非Serialiazable,对象 所以需要精简代码

            if(event==com.example.smart_video.model.Constants.EventEnum.网络请求成功.ordinal){
                val result=args[0] as String
                installData(result)
            }
        }
    }
            )


    }


    /**
     * initPlayVideo只需要一次就行了  切换舞蹈调用
     * */
    fun initVideo() {
        sv_texture_w = 0f
        // 创建一个MediaPlayer对象
        mMediaPlayer = MediaPlayer()

        mMediaPlayer?.setOnPreparedListener(MediaPlayer.OnPreparedListener {
            mMediaPlayer?.setLooping(true);
            mMediaPlayer?.start()
            if(mute){
               mMediaPlayer?.setVolume(0f, 0f)
            }

        })

        mMediaPlayer?.setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener { mediaPlayer, videoX, videoY ->

            if (sv_texture_w == 0f) {
                sv_texture_w = m_surfaceView!!.getMeasuredWidth().toFloat()
                sv_texture_h = m_surfaceView!!.getMeasuredHeight().toFloat()

            }

            updateTextureViewSizeCenter(
                mMediaPlayer!!.videoWidth.toFloat(),
                mMediaPlayer!!.videoHeight.toFloat()
            )

        })


        // 设置相关的监听器
        mMediaPlayer?.setOnCompletionListener(MediaPlayer.OnCompletionListener {
        //媒体播放完毕时会触发。但是当OnErrorLister返回false，或者MediaPlayer没有设置OnErrorListener时，这个监听也会被触发。

        })

        mMediaPlayer?.setOnErrorListener(MediaPlayer.OnErrorListener { mediaPlayer, what, extra ->
            false
        })


        //播放时屏幕保持唤醒
        mMediaPlayer?.setScreenOnWhilePlaying(true)
        mMediaPlayer?.setOnBufferingUpdateListener(object : MediaPlayer.OnBufferingUpdateListener {
            override fun onBufferingUpdate(p0: MediaPlayer?, precent: Int) {//进度百分比
//                Log.e(TAG, "onBufferingUpdate: ====>>" + precent)  //只有在线视频才会打印  如果视频已缓存会导致这里没有回调
                binding.progress
            }
        })


//        *****************华丽分界线*************************
        removeVideoContainer()
        m_surfaceView =
            LayoutInflater.from(context)
                .inflate(R.layout.layout_list_player_view, null) as TextureView

        m_surfaceView!!.setOnClickListener {
            if (mMediaPlayer!!.isPlaying) {
                pausePlay()
            } else {
                resumePlay()
            }

        }

        m_surfaceView!!.surfaceTextureListener = this  //after
    }

    /**重新计算video的显示位置，让其全部显示并据中
     *  Math.min
     * */
    private fun updateTextureViewSizeCenter(video_w: Float, video_h: Float) {
        val sx = sv_texture_w / video_w
        val sy = sv_texture_h / video_h
        val matrix = Matrix()
        val maxScale = Math.min(sx, sy);   //min   //min

        //第1步:把视频区移动到View区,使两者中心点重合
        matrix.preTranslate((sv_texture_w - video_w) / 2, (sv_texture_h - video_h) / 2);

        //第2步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来
        matrix.preScale(video_w / sv_texture_w, video_h / sv_texture_h);

        //第3步,等比例放大或缩小,直到视频区的一边超过View一边, 另一边与View的另一边相等. 因为超过的部分超出了View的范围,所以是不会显示的,相当于不裁剪了
        matrix.postScale(
            maxScale,
            maxScale,
            sv_texture_w / 2,
            sv_texture_h / 2
        );//后两个参数坐标是以整个View的坐标系以参考的


        m_surfaceView!!.setTransform(matrix)
        m_surfaceView!!.postInvalidate()
    }


    /**
     * 从原来的父布局列表item移除--first
     * */
    fun removeVideoContainer() {
        if (m_surfaceView != null) {
            val parent = m_surfaceView!!.getParent()

            if (parent != null && (parent as ViewParent) is RelativeLayout) { //从原来的父布局列表item移除--first
                (parent as ViewGroup).removeView(m_surfaceView)
            }
        }
    }

    fun addVideoContainer(relativeLayout: RelativeLayout) {
        (relativeLayout as RelativeLayout).addView(m_surfaceView, 1)
    }

    /**
     *
     * 切换舞蹈mMediaPlayer?.reset()  是重点
     *
    　prepare方法是将资源同步缓存到内存中,一般加载本地较小的资源可以用这个,
    如果是较大的资源或者网络资源建议使用prepareAsync方法,异步加载.但如果想让资源启动,即start()起来,
    因为在异步中,如果不设置监听直接start的话,是拿不到这个资源,如果让线程睡眠一段时间,则可以取得资源,因为这个时候,异步线程已经取得资源,
    但不可能使用线程睡眠的方式来获取资源啊.所以就需要设置监听事件setOnPreparedListener();
    来通知MediaPlayer资源已经获取到了,然后实现onPrepared(MediaPlayer mp)方法.在里面启动
     *
     * */
    private fun startPlayVideo(position: Int) {
        val homeListAdapter = binding.listView.adapter as HBomeListAdapter
        val relativeLayout = binding.listView.findViewByPos(position) as RelativeLayout

        removeVideoContainer()
        addVideoContainer(relativeLayout)

        val base_item = homeListAdapter!!.dataList!!.get(position) as BaseDataItem
        val single_dance = base_item.data as VideoData

        // 设置播放的视频数据源
        try {
            val t_url = TENCENT_BUCKET_OFFICE_URL + single_dance.video_url
            val proxy: HttpProxyCacheServer = ABpplication.proxy!!
            val video_url = proxy.getProxyUrl(t_url)

//            Log.e(TAG, "startPlayVideo: ====>>" + video_url)
            mMediaPlayer?.reset();
            mMediaPlayer?.setDataSource(video_url)

            // 播放准备，使用异步方式，配合OnPreparedListener
            mMediaPlayer?.prepareAsync()
        } catch (e: IOException) {
            e.printStackTrace()
//            CommonUtils.showToast("播放异常 请重新进入")
        }

    }

    /**
     * 暂停播放
     */
    private fun pausePlay() {
        if (mMediaPlayer != null) {
            mMediaPlayer!!.pause()
        }
    }

    /**
     * 恢复播放
     */
    private fun resumePlay() {
        if (mMediaPlayer != null) {
            mMediaPlayer!!.start()
        }
    }

    /**
     * 销毁
     */
    fun stopPlay() {
        if (mMediaPlayer != null) {
            mMediaPlayer?.stop()
            mMediaPlayer?.release()
            mMediaPlayer = null
        }
    }

    override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
        val surface_t = Surface(surface);
        if (mMediaPlayer != null) {
            mMediaPlayer!!.setSurface(surface_t)
        }

    }

    override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {

    }

    override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {

    }

    override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
        return true
    }

    companion object {
        private const val TAG = "MainFragment"
    }
}